package com.atguigu.gmall.scheduled.config;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.scheduled.mapper.CartMapper;
import com.atguigu.gmall.scheduled.pojo.Cart;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.KeyBoundCursor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class MyJobHandler {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private CartMapper cartMapper;

    private static final String KEY_PREFIX = "cart:info:";
    private static final String EXCEPTION_KEY = "cart:exception:userId";


    /**
     * 定时任务将mysql写入失败的数据从Redis中读取重新写入到mysql
     *
     * @param param userId
     * @return
     */
    @XxlJob(("dataSyncHandler"))
    public ReturnT<String> dataSyncHandler(String param) {
        // 读取redis中失败用户的信息
        BoundSetOperations<String, String> setOps = this.redisTemplate.boundSetOps(EXCEPTION_KEY);

        // 随机获取并移除一个用户  pop方法
        String userId = setOps.pop();
        while (userId != null) {

            // 将该用户的mysql数据库购物车全部删除
            this.cartMapper.delete(new UpdateWrapper<Cart>().eq("user_id", userId));

            // 读取Redis中的该用户的所有购物车记录 如果redis中没有对应用户的购物车直接结束
            if (!this.redisTemplate.hasKey(KEY_PREFIX+userId)){
                return ReturnT.SUCCESS;
            }
            BoundHashOperations<String, Object, Object> hashOps = this.redisTemplate.boundHashOps(KEY_PREFIX + userId);
            // 遍历新增
            List<Object> cartJsons = hashOps.values();
            cartJsons.forEach(cartJson->{
                Cart cart =JSON.parseObject(cartJson.toString(), Cart.class);
                // 将cart新增到mysql
                cart.setId(null);
                this.cartMapper.insert(cart);
            });
            userId = setOps.pop();  // 不断循环
        }

        return ReturnT.SUCCESS;
    }


    @XxlJob("myJobHandler")
    public ReturnT<String> execute(String param) {
        XxlJobLogger.log("使用XxlJobLogger打印执行日志，O(∩_∩)O");
        System.out.println("我的任务执行了：" + param + "，线程：" + Thread.currentThread().getName());
        return ReturnT.SUCCESS;
    }
}